package cn.xtits.xtf.common.spring.db.readwrite;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;


public class DynamicReadWriteDataSourceRoute extends AbstractRoutingDataSource {

    public static final Logger logger = LoggerFactory.getLogger(DynamicReadWriteDataSourceRoute.class);

    private AtomicInteger counter = new AtomicInteger();

    /**
     * 主库
     */
    private DataSource masterDataSource;

    /**
     * 备库列表
     */
    private List<DataSource> slaveDataSourceList;

    /**
     * 选取数据源
     * @return
     */
    @Override
    protected DataSource determineTargetDataSource() {
        DataSource dataSource = null;

        if (DynamicReadWriterDataSourceHolder.isMaster()) dataSource = masterDataSource;

        if (DynamicReadWriterDataSourceHolder.isSlave()) {
            if (slaveDataSourceList == null || slaveDataSourceList.size() == 0) {
                /** 如果没有配置备库列表,则默认从主库读 **/
                dataSource = masterDataSource;
            } else {
                dataSource = getRandomSlave();
            }
        }

        if (dataSource == null) throw new RuntimeException("dataSource仲裁异常..");

        if (dataSource instanceof DruidDataSource) {
            DruidDataSource druidDataSource = (DruidDataSource) dataSource;
            String rawJdbcUrl = druidDataSource.getRawJdbcUrl();
            logger.debug("获得数据源地址: {}",rawJdbcUrl);
        }
        return dataSource;
    }

    public DataSource getMasterDataSource() {
        return masterDataSource;
    }

    public void setMasterDataSource(DataSource masterDataSource) {
        this.masterDataSource = masterDataSource;
    }

    public List<DataSource> getSlaveDataSourceList() {
        return slaveDataSourceList;
    }

    public void setSlaveDataSourceList(List<DataSource> slaveDataSourceList) {
        this.slaveDataSourceList = slaveDataSourceList;
    }

    private DataSource getRandomSlave() {
        Random random = new Random();
        int slaveSize = slaveDataSourceList.size();
        int index = random.nextInt(slaveSize);
        return slaveDataSourceList.get(index);
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return null;
    }

    @Override public void afterPropertiesSet() {
    }
}
